// void, Obj This

Building this;
Unit u;
int p, i;
point pos, pp;
rect rc;
str names;
bool cheat, setplayer;
ObjList ol, olSentry, olCaptain, olOther;

Sleep(10360+rand(GetConst("RandTimeStart"))+GetConst("AddTimeStart"));

this = This.AsBuilding();

if (!.IsValid()) return;

while(.IsValid){
	if (!.settlement.IsIndependent()) break;
	Sleep(5000);
}
p = .player;

names = "/1/Outpost/"+.name;       
//pr("outpost sentry start");
setplayer = false;

if(!.settlement.IsIndependent()){
  	
	if(.settlement.UnitsCount > 0){
		olSentry = .settlement.Units.ObjClass("SentryOutpost");
		olCaptain = .settlement.Units.ObjClass("CaptainOutpost");
		ol.AddList( olCaptain );
		ol.AddList( olSentry ); 
		ol = ol.ObjEnemy(.player);
		for(i=0; i<ol.count; i+=1){
							
			Sleep(rand(20)+10);
			u = ol[i].AsUnit;
			if(u.IsValid){
				rc = GetMapRect();
				pos.Set(0, .sight / 2);
				pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.SetCommand("advance", pp);
				pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
				pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
				pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
				pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
			}
		}
	}
}

while(.IsValid){
	Sleep(3000);
	if(!.settlement.IsIndependent()){
  	
		if(.settlement.UnitsCount > 0){
			
			//pr(EnvReadString(this, "SentryOutpostBuying"));
			if(EnvReadString(this, "SentryOutpostBuying") == "yes"){
				str nameu;
				
				olSentry = .settlement.Units.ObjClass("SentryOutpost");
				olCaptain = .settlement.Units.ObjClass("CaptainOutpost");
				ol.AddList( olCaptain );
				ol.AddList( olSentry ); 
				ol = ol.ObjEnemy(.player);
				//ol = ol.ObjAlly(.player);
				//pr("ol count przed: "+ol.count);
				for(i=0; i<ol.count; i+=1){
					
					Sleep(rand(20)+10);
					u = ol[i].AsUnit;
					if(u.IsValid){
						nameu = "/1/SentryName/"+u.name;
						//pr(EnvReadString(names));
						if(EnvReadString(nameu) != names)
							olOther.Add(u);
					}
				}
				ol.RemoveList(olOther);
				//pr("ol count po: "+ol.count);
				if(ol.count > 0){
					Query qBT;
					Hero captain; 
					str class_unit, class_captain;
					int max_unit, j, k, y, d;
					
					if(EnvReadInt(names) != 1)
						EnvWriteInt(names, 1);
					max_unit = olSentry.count;
					
					class_unit = olSentry[0].AsUnit.class;
					class_captain = olCaptain[0].AsHero.class;
					
					captain = olCaptain[0];
						
					qBT = ClassPlayerObjs("BaseTownhall", .player); 
					
					while(ol.count > 0){

						ol.ClearDead();
						cheat = false;
						
						for(i=0; i<ol.count; i+=1){
							
							u = ol[i].AsUnit;
							if(u.IsValid){
								if(u.player != 15)
								if(u.player != .player){
									u.SetPlayer(.player);
									if(setplayer == false)
										setplayer = true;
								}
									
								if(!u.InHolder){
									
									d = u.DistTo(.pos);
									if(d >= 2000){
										if(u.player == .player){
											if(!qBT.IsEmpty){
												u.Deselect();
												u.SetNoselectFlag(true);
												u.SetCommand("enter", .settlement.GetCentralBuilding);
												if(u.IsHeirOf("CaptainOutpost")){
													//View(u.pos, false );
													cheat = true;
												}
											}
										}
										else { break; }
									}
								}
							}
							Sleep(rand(10)+5);
						}
						if(setplayer == true){
							SwapSelectedObj(this, this);
							setplayer = false;
						}
						//if(EnvReadString(this, "SentryBlockOut") != "no")
							//EnvWriteString(this, "SentryBlockOut", "no");
						if(cheat == true){
							for(y=0; y<15; y+=1){
								for(i=0; i<ol.count; i+=1){ 
									
									u = ol[i].AsUnit;
									if(u.IsValid){
										u.SetCommand("enter", .settlement.GetCentralBuilding);
										u.Deselect();
									}
								}
								Sleep(200); 
							}
						} else {       
							Sleep(3000);
						} 
						if(p != .player){ // gdy fort zostanie przejety
							
							for(i=0; i<ol.count; i+=1){
								u = ol[i].AsUnit;
								
								if(u.IsValid){
									if(u.player != 15){
										u.SetPlayer(15);
										if(u.IsHeirOf("CaptainOutpost")){
											rc = GetMapRect();
											pos.Set(0, .sight / 2);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.SetCommand("advance", pp);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.AddCommand(false, "patrol", pp);
										} else if(!u.hero.IsValid){
											rc = GetMapRect();
											pos.Set(0, .sight / 2);
											pos.Rot(rand(360));     pp = pos + .pos; pp.IntoRect(rc); u.SetCommand("advance", pp);
										}
									}
								}
								Sleep(5);
							}
							break;
						}
						j+=1;
							
						if(j >= 10){
							j = 0;
							cheat = false;
							olSentry.ClearDead();
							olCaptain.ClearDead(); 
							ol.ClearDead();
							
							for(i=0; i<ol.count; i+=1){
								
								u = ol[i].AsUnit;
								if(u.IsValid){
									u.SetNoselectFlag(false);
								}
								Sleep(2);
							}
							if(olCaptain.count == 0 || !captain.IsValid){
								Sleep(rand(100)+100);
								captain = Place(class_captain, .pos, .player);
								if(captain.IsValid){
									CreateFeedback("DefensiveCry", captain.AsUnit, -1);
									olCaptain.Add(captain);
									ol.Add(captain);
									.settlement.ForceAddUnit(captain);
									olSentry.SetCommand("attach", captain); 
								}
							}
							if(olSentry.count < max_unit && olSentry.count > 0 && !captain.AsHero.IsHeroArmyFull){
								Unit newSentry;
								Sleep(rand(100)+100);
								newSentry = Place(class_unit, .pos, .player);
								if(newSentry.IsValid){
									olSentry.Add(newSentry);
									ol.Add(newSentry);
									.settlement.ForceAddUnit(newSentry);
									if(captain.IsValid)
										newSentry.SetCommand("attach", captain);
								}
							}
						}
						k+=1;
						//pr(k);
						if(k >= 40){
							k = 0;
							if(captain.IsValid){
								if(captain.AsHero.health >= captain.AsHero.maxhealth){
									if(captain.AsHero.inherentlevel < 30)
										captain.AsHero.SetLevel(captain.AsHero.inherentlevel+1);
								}
							}
						}   
					}
					EnvWriteString(this, "SentryOutpostBuying", "no"); 
					
					if(EnvReadInt(names) != 0)
						EnvWriteInt(names, 0);
				}
			}
		}
    }
    
	if(p != .player) break;
    Sleep(5000);
}